package com.whty.cms.filewps.util;

import org.apache.commons.codec.binary.Base64;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.Map;

public final class CryptoClient {
	
	// 秘钥算法: RSA非对称加密算法
	private static final String KEY_ALGORITHM = "RSA";
	
	// 签名算法
	private static final String SIGN_ALGORITHM = "SHA1withRSA";
	
	// BASE64编码
	private static Base64 base64 = new Base64();
	
	// 公钥对象
	private PublicKey publicKey;
	
	private static Map<String,CryptoClient> cache = MapUtil.newHashMap();
	
	private CryptoClient(String pubKey) {
		try {
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
			KeySpec keySpec = new X509EncodedKeySpec(base64.decode(pubKey));
			publicKey = keyFactory.generatePublic(keySpec);
		} catch(Exception ex) {
			throw new RuntimeException(ex);
		}
	}
	
	public static CryptoClient getInstance(String pubKey) {
		CryptoClient client = cache.get(pubKey);
		if (client != null) {
			return client;
		}
		client = new CryptoClient(pubKey);
		cache.put(pubKey, client);
		return client;
	}
	
	/**
	 * @author	xiongxiaofei
	 * @date	2015年3月19日
	 * @desc	公钥验证数字签名
	 * @param	key
	 * @param	signatrueStr
	 * @return
	 */
	public boolean verify(String key, String signatrueStr) {
		boolean result = false;
		Signature signature = null;
		try {
			signature = Signature.getInstance(SIGN_ALGORITHM);
			signature.initVerify(publicKey);
			signature.update(key.getBytes());
			result = signature.verify(base64.decode(signatrueStr));
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return result;
	}
	
	/**
     * @return
     * @author xiongxiaofei
     * @date 2015年3月19日
     * @desc 生成私钥对象
     */
    private static PrivateKey getPrivateKey(String priKey) {
        PrivateKey privateKey = null;
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            KeySpec keySpec = new PKCS8EncodedKeySpec(base64.decode(priKey));
            privateKey = keyFactory.generatePrivate(keySpec);
        } catch (Exception ex) {
        }
        return privateKey;
    }
	
    /**
     * @return
     * @author xiongxiaofei
     * @date 2015年3月19日
     * @desc 私钥生成数字签名
     * @param    key
     */
    public static String getSignature(String key, String priKey) {
        String result = null;
        PrivateKey privateKey = getPrivateKey(priKey);
        try {
            Signature signature = Signature.getInstance(SIGN_ALGORITHM);
            signature.initSign(privateKey);
            signature.update(key.getBytes());
            byte[] data = signature.sign();
            result = base64.encodeToString(data);
        } catch (Exception ex) {
        	ex.printStackTrace();
        }
        return result;
    }
    
	public static void main(String[] args) {
		String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmICtzX1RZLBODdVHkf9EUpcI3FJK4XZ85cMRrYTQ2mtqpvogRwuQBBiPqJNyCO5dEMr6fgTQ5/o+cPmHOJc1jOtEs3KSOW8h/73XuJ9LvRHS6uoU/ADUjbuRCmqCJPqIHJnXul6jBzV9AgW36FhehKzOgWcqAfuIJRh7Enog0CQIDAQAB";
		CryptoClient client = CryptoClient.getInstance(publicKey);
		Long time = new Date().getTime();
		String srcData = "16499bd775d14c9c90da2ae4c718718c&POST&/upload/getSimpleCosAuthorization&"+time;
		String priaveKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKYgK3NfVFksE4N1UeR/0RSlwjcUkrhdnzlwxGthNDaa2qm+iBHC5AEGI+ok3II7l0Qyvp+BNDn+j5w+Yc4lzWM60SzcpI5byH/vde4n0u9EdLq6hT8ANSNu5EKaoIk+ogcmde6XqMHNX0CBbfoWF6ErM6BZyoB+4glGHsSeiDQJAgMBAAECgYAFghmOuMF2N3TqLfCqL+bB1YEsDF2VCV2nLOsGWHG/wcCwUiX22MxwkECOmexJ0SoB0+DoLwOJTLx8RME/cZduviJL/bR24tpPACnwivxzGD+vDXe+1ZPOnuK9v6D+nl+A3VPftk/SrEiUfTlCWrRmx+G0gfs2xtlD57yd4tvvkQJBAOA1+Twf249irQZaMulJeREcvzh9ev86L2jQCdRazPc3ocdO4ITA98ClfJKgALCqwqLFH4r0fyl+XQ3frDk1yNUCQQC9ressikidXmtM5mX1fveXRa+9E6D59Db5yL+9lbLtv4tThS4YnXQJR4RWvgB4EWRUxhuHW79aVRflt+T5jBhlAkA1HdRL4Cg90dy30oqZJeTenvbWRTPsXzZ4GEEb498G+lEDTLZ3/Nc09n+KpQlE0U+HDDgqzT2K8PrOnJzKeOl5AkAHBjjOVnSn90Yr++BMvh33KSp/6wksGIIsr+WB5NhSe6RyPF1fpf0VFuPsvm6QA7zectO0KI6mjr4q0KuXHjwNAkEAgoCCh87+v1UX/UO520ZlQ8L2RL1jolmvvRSfsSDO/fLgKPGlqkXbUOE77IZJ/uImbW9r7EnbeZsW/f0SKVMnyA==";
		String signData =getSignature(srcData,priaveKey);
		System.out.println(time);
		System.out.println(signData);
//		boolean flag = client.verify(srcData, signData);
//		System.out.println(flag);
	}
}
